﻿
//using CSRedis;
using System;
using System.Collections.Generic;

namespace Common.Framework.Core.Cache
{
    /// <summary>
    /// 缓存接口
    /// </summary>
    public interface ICache
    {
        /// <summary>
        /// 获取缓存值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        TEntity Get<TEntity>(string key);

        /// <summary>
        /// 添加缓存内容(滑动过期)
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="expiresAtSecond"></param>
        void SetSliding<TEntity>(string key, TEntity value, int expiresAtSecond);

        /// <summary>
        /// 添加缓存内容(定时过期)
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="expires">缓存时间</param>
        void Set<TEntity>(string key, TEntity value, DateTime expires);

        /// <summary>
        /// 添加缓存内容(定时过期)
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="expiresAtSecond">缓存时间</param>
        void Set<TEntity>(string key, TEntity value, int expiresAtSecond);

        /// <summary>
        /// 添加或获取缓存
        /// </summary>
        /// <typeparam name="TEntity">泛型实体</typeparam>
        /// <param name="fuc">数据源方法</param>
        /// <param name="key">缓存key</param>
        /// <param name="cacheSeconds">缓存时间（秒）</param>
        /// <returns></returns>
        TEntity Set<TEntity>(Func<TEntity> fuc, string key, int cacheSeconds);

        /// <summary>
        /// 添加Hash表
        /// </summary>
        /// <param name="key">缓存Key</param>
        /// <param name="keyValuePairs">待设置的值</param>
        /// <param name="expiresAtSecond">过期时间</param>
        void SetHash<TEntity>(string key, IEnumerable<KeyValuePair<string, TEntity>> keyValuePairs, int expiresAtSecond);

        /// <summary>
        /// 添加Hash表
        /// </summary>
        /// <typeparam name="TEntity">泛型</typeparam>
        /// <param name="key">缓存Key</param>
        /// <param name="hashId">hashId</param>
        /// <param name="value">值</param>
        /// <param name="expiresAtSecond">过期时间</param>
        void SetHash<TEntity>(string key, string hashId, TEntity value, int expiresAtSecond);

        /// <summary>
        /// 添加Hash表
        /// </summary>
        /// <param name="key">缓存Key</param>
        /// <param name="hashId">hashId</param>
        /// <param name="expiresAtSecond">过期时间</param>
        /// <param name="isCache">是否读取换存</param>
        TEntity GetHash<TEntity>(Func<TEntity> fuc, string key, string hashId, int expiresAtSecond, bool isCache = true);

        /// <summary>
        /// 获取Hash表某条字段的值
        /// </summary>
        /// <typeparam name="TEntity">泛型</typeparam>
        /// <param name="key">缓存Key</param>
        /// <param name="hashId">hash表字段Id</param>
        /// <returns></returns>
        TEntity GetHash<TEntity>(string key, string hashId);

        /// <summary>
        /// 获取Hash表所有记录
        /// </summary>
        /// <typeparam name="TEntity">泛型</typeparam>
        /// <param name="key">缓存Key</param>
        /// <returns></returns>
        List<TEntity> GetHash<TEntity>(string key);

        #region 列表(list)  

        #region 同步
        /// <summary>
        /// 向列表中增加一个或多个值
        /// 示例：RPush("my-list", "item1", "item2", "item3", "item4"); 
        /// </summary>
        /// <typeparam name="TEntity">值类型</typeparam>
        /// <param name="key">缓存key（不含前缀）</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        long RPush<TEntity>(string key, params TEntity[] value);

        /// <summary>
        /// 获取列表指定范围内元素
        /// </summary>
        /// <param name="key">缓存key（不含前缀）</param>
        /// <param name="start">起始索引</param>
        /// <param name="stop">结束索引（-1即可返回所有元素）</param>
        /// <returns></returns>
        string[] LRange(string key, long start = 0, long stop = -1);

        #endregion

        #region 异步
        /// <summary>
        /// 向列表中增加一个或多个值
        /// 示例：RPush("my-list", "item1", "item2", "item3", "item4"); 
        /// </summary>
        /// <typeparam name="TEntity">值类型</typeparam>
        /// <param name="key">缓存key（不含前缀）</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        System.Threading.Tasks.Task<long> RPushAsync<TEntity>(string key, params TEntity[] value);

        /// <summary>
        /// 获取列表指定范围内元素
        /// </summary>
        /// <param name="key">缓存key（不含前缀）</param>
        /// <param name="start">起始索引</param>
        /// <param name="stop">结束索引（-1即可返回所有元素）</param>
        /// <returns></returns>
        System.Threading.Tasks.Task<string[]> LRangeAsync(string key, long start, long stop = -1);

        #endregion

        #endregion

        #region  有序集合(sorted set)

        #region 同步
        /// <summary>
        /// 向集合添加一个或多个成员
        /// </summary>
        /// <typeparam name="TEntity">泛型</typeparam>
        /// <param name="key">缓存key</param>
        /// <param name="seconds">过期秒数</param>
        /// <param name="members"一个或多个成员></param>
        /// <returns></returns>
        long SAdd<TEntity>(string key, int seconds, params TEntity[] members);

        /// <summary>
        /// 返回集合中的所有成员
        /// </summary>
        /// <param name="key">缓存key</param>
        /// <param name="addprefix">key是否已经加了前缀</param>
        /// <returns></returns>
        string[] SMembers(string key, bool addprefix = false);

        #endregion

        #region 异步 
        /// <summary>
        /// 向集合添加一个或多个成员
        /// </summary>
        /// <typeparam name="TEntity">泛型</typeparam>
        /// <param name="key">缓存key</param>
        /// <param name="seconds">过期秒数</param>
        /// <param name="members"一个或多个成员></param>
        /// <returns></returns>
        System.Threading.Tasks.Task<long> SAddAsync<TEntity>(string key, int seconds, params TEntity[] members);

        /// <summary>
        /// 返回集合中的所有成员
        /// </summary>
        /// <param name="key">缓存key</param>
        /// <param name="addprefix">key是否已经加了前缀</param>
        /// <returns></returns>
        System.Threading.Tasks.Task<string[]> SMembersAsync(string key, bool addprefix = false);
        #endregion
        #endregion

        /// <summary>
        /// 清除缓存
        /// </summary>
        /// <param name="key">待清除的key</param>
        void Remove(string key);

        /// <summary>
        /// 清除所有缓存
        /// </summary>
        void Remove();

        /// <summary>
        /// 清除key以startsWithKey开头的缓存
        /// </summary>
        void RemoveStartsWith(string startsWithKey);

        #region Distributed Locks

        ///// <summary>
        ///// 开启分布式锁，true 锁定中 false 未锁定
        ///// </summary>
        ///// <param name="key">锁名称</param>
        ///// <param name="timeoutSeconds">超时（秒）</param>
        ///// <param name="autoDelay">自动延长锁超时时间，看门狗线程的超时时间为timeoutSeconds/2 ， 在看门狗线程超时时间时自动延长锁的时间为timeoutSeconds。除非程序意外退出，否则永不超时。</param>
        ///// <returns>false 锁定中 true 未锁定</returns>
        //CSRedisClientLock LockTake(string key, int timeoutSeconds, bool autoDelay = false);

        ///// <summary>
        ///// 释放锁
        ///// </summary>
        ///// <param name="cSRedisClientLock"></param>
        ///// <returns></returns>
        //bool LockRelease(CSRedisClientLock cSRedisClientLock);

        #endregion
    }
}
